# -*- coding:utf-8 -*-
import sqlite3
import threading


class DbConfig:
    def __init__(self):
        pass


class SqliteConfig:
    def __init__(self, dbPath: str = None):
        self.dbPath: str = dbPath


class PymysqlConfig:
    def __init__(self, host: str, port: int, userName: str, password: str, dbName: str, charset: str = "UTF8"):
        self.host: str = host
        self.port: int = port
        self.userName: str = userName
        self.password: str = password
        self.dbName: str = dbName
        self.charsets: str = charset


class DbUtil(object):
    def __init__(self, dbConfig: DbConfig):
        self.dbConfig: DbConfig = dbConfig
        self.conn = None
        self.cur = None

    # 链接数据库
    def connect(self):
        """ 获取连接 """
        pass

    def close(self):
        """关闭链接"""
        self.cur.close()
        self.conn.close()
        self.cur = None
        self.conn = None

    def get_one(self, sql):
        """查询一条数据"""
        pass

    def get_all(self, sql):
        """查询列表数据"""

    def save(self, sql):
        """保存数据"""
        pass

    def update(self, sql):
        """更新数据"""
        pass

    def delete(self, sql):
        """删除数据"""
        pass


class SqliteUtil(DbUtil):
    ins = {}
    ins_lock = threading.Lock()

    def __init__(self, dbConfig: SqliteConfig):
        super(SqliteUtil, self).__init__(dbConfig)
        self.dbConfig: SqliteConfig = dbConfig
        self.connect()


    @classmethod
    def get_instance(cls, dbConfig: SqliteConfig):
        with cls.ins_lock:
            to_new = False
            if dbConfig.dbPath in cls.ins:
                if threading.currentThread() == cls.ins[dbConfig.dbPath]['thread']:
                    return cls.ins[dbConfig.dbPath]['ins']
                else:
                    del cls.ins[dbConfig.dbPath]
                    to_new = True
            else:
                to_new = True
            if to_new:
                ins = cls(dbConfig)
                cls.ins[dbConfig.dbPath] = {"ins": ins, "thread": threading.currentThread()}
                return ins


    def connect(self):
        if self.conn is None:
            self.conn = sqlite3.connect(self.dbConfig.dbPath)
            self.cur = self.conn.cursor()

    def get_one(self, sql):
        res = None
        try:
            self.connect()
            self.cur.execute(sql)
            res = self.cur.fetchone()
        except Exception as e:
            self.close()
            raise e
        return res

    def get_all(self, sql):
        res = None
        try:
            self.connect()
            self.cur.execute(sql)
            res = self.cur.fetchall()
        except Exception as e:
            self.close()
            raise e
        return res

    # 插入数据
    def __insert(self, sql):
        count = 0
        try:
            self.connect()
            count = self.cur.execute(sql)
            self.conn.commit()
        except Exception as e:
            print("操作失败！" + str(e))
            self.conn.rollback()
            raise e
        return count

    # 保存数据
    def save(self, sql):
        return self.__insert(sql)

    # 更新数据
    def update(self, sql):
        return self.__insert(sql)

    # 删除数据
    def delete(self, sql):
        return self.__insert(sql)


class MySQLUtil(DbUtil):
    """MySQL util"""

    def __init__(self, dbConfig: PymysqlConfig):
        super(SqliteUtil, self).__init__(dbConfig)
        self.dbConfig: PymysqlConfig = dbConfig
        self.connect()

    # 链接数据库
    def connect(self):
        # if self.conn is None:
        #     self.conn = pymysql.Connect(
        #         host=self.host,
        #         port=self.port,
        #         user=self.userName,
        #         passwd=self.password,
        #         db=self.dbName,
        #         charset=self.charsets
        #     )
        #     self.cursor = self.db.cursor()
        pass


    # 主键查询数据
    def get_one(self, sql):
        res = None
        try:
            self.get_con()
            self.cur.execute(sql)
            res = self.cur.fetchone()
            self.close()
        except Exception as e:
            print("查询失败！" + str(e))
            raise e
        return res

    # 查询列表数据
    def get_all(self, sql):
        res = None
        try:
            self.get_con()
            self.cur.execute(sql)
            res = self.cur.fetchall()
            self.close()
        except Exception as e:
            print("查询失败！" + str(e))
            raise e
        return res

    # 插入数据
    def __insert(self, sql):
        count = 0
        try:
            self.get_con()
            count = self.cur.execute(sql)
            self.db.commit()
            self.close()
        except Exception as e:
            print("操作失败！" + str(e))
            self.db.rollback()
            raise e
        return count

    # 保存数据
    def save(self, sql):
        return self.__insert(sql)

    # 更新数据
    def update(self, sql):
        return self.__insert(sql)

    # 删除数据
    def delete(self, sql):
        return self.__insert(sql)